/*
 * Title:        CloudScheduler Toolkit
 * Description:  a Toolkit for Modeling and Simulation of Job Scheduling and Resource Provisioning in Cloud System
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 * Author:       Fuhui Wu
 *
 * Copyright (c) 2013-2014, The National University of Defense Technology, China
 */

package org.nudt.jCloud.example.evaluation;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.nudt.jCloud.infrastructure.SlotType;
import org.nudt.jCloud.util.ExponentialDistribution;
import org.nudt.jCloud.workload.AllJob;
import org.nudt.jCloud.workload.BatchJob;
import org.nudt.jCloud.workload.LogicalJob;
import org.nudt.jCloud.workload.Task;
import org.nudt.jCloud.workload.Workload;

public class ComplementWorkload {
	public static void generate(Workload wl1, Workload wl2, SlotType slotType){
		double avgJobInterarrivalTime = 100;
		double avgTaskDuration = 50;
		double jobSizeDistribution = 0.5;
		
		ExponentialDistribution jobArrivalTimeGen = new ExponentialDistribution(avgJobInterarrivalTime);
		ExponentialDistribution avgTaskDurationGen = new ExponentialDistribution(avgTaskDuration);
		Random taskNumR = new Random(System.currentTimeMillis());
		double arrivalTime1 = 0;
		double arrivalTime2 = 0;
		for(int m = 0; m<100; ++m){
			int maxTaskNumPerJob1 = 30+m*1;
			int maxTaskNumPerJob2 = 160-maxTaskNumPerJob1;
			for(int i=0; i<50; ++i){
				arrivalTime1 += jobArrivalTimeGen.sample();
				List<Task> taskList1 = new ArrayList<Task>();
				double duration1 = avgTaskDurationGen.sample();
				int taskNum1 = 0;
				if(maxTaskNumPerJob1 <= 1){
					taskNum1 = 1;
				}else{
					if(taskNumR.nextDouble()<=jobSizeDistribution){
						taskNum1 = taskNumR.nextInt(maxTaskNumPerJob1/2)+1;
					}else{
						taskNum1 = taskNumR.nextInt(maxTaskNumPerJob1/2)+maxTaskNumPerJob1/2+1;
					}				
				}
				for(int j=0; j<taskNum1; ++j){
					taskList1.add(new Task(j, duration1));
				}
				LogicalJob andJob1 = new AllJob(arrivalTime1, wl1);
				andJob1.add(new BatchJob(arrivalTime1, taskList1, slotType, andJob1));
				wl1.add(andJob1);
				
				arrivalTime2 += jobArrivalTimeGen.sample();
				List<Task> taskList2 = new ArrayList<Task>();
				double duration2 = avgTaskDurationGen.sample();
				int taskNum2 = 0;
				if(maxTaskNumPerJob2 <= 1){
					taskNum2 = 1;
				}else{
					if(taskNumR.nextDouble()<=jobSizeDistribution){
						taskNum2 = taskNumR.nextInt(maxTaskNumPerJob2/2)+1;
					}else{
						taskNum2 = taskNumR.nextInt(maxTaskNumPerJob2/2)+maxTaskNumPerJob2/2+1;
					}
				}
				for(int j=0; j<taskNum2; ++j){
					taskList2.add(new Task(j, duration2));
				}
				LogicalJob andJob2 = new AllJob(arrivalTime2, wl2);
				andJob2.add(new BatchJob(arrivalTime1, taskList2, slotType, andJob2));
				wl2.add(andJob2);
			}
		}		
	}

}
